home *** CD-ROM | disk | FTP | other *** search
/ Univers Interactif 3 / INTERACTIF.BIN / mac / Planete.net / Internet Confirmés_Vrac / NetAgent.sea / src / nntp_tcp.c < prev    next >
C/C++ Source or Header  |  1992-06-15  |  10KB  |  377 lines

  1. /*
  2. This is an unsupported product. It was developed as part of a study at Ostfold
  3. Regional College, Norway in the spring of 1992.
  4.  
  5. You use this software at your own risk. Neither the authors nor the Ostfold
  6. Regional College nor any other person or organization except yourself is
  7. responsible for any damage or loss of data derived from the use of this
  8. software. You may distribute this software freely as long as it is in its
  9. original form and all of its files are included. If you make any changes to any
  10. part of this software or the files distributed with it, please state so and do
  11. NOT distribute it under its original name.
  12. */
  13.  
  14.  
  15. #include <stdio.h>
  16. #include <sys/types.h>
  17. #include <sys/socket.h>
  18. #include <netinet/in.h>
  19. #include <netdb.h>
  20. #include <sys/types.h>
  21. #include <sys/time.h>
  22.  
  23. #define BACKLOG 10
  24. #define MAXHOSTNAME 32
  25.  
  26. #define RETURN          13
  27. #define LINEFEED        10
  28.  
  29. char *myname;
  30. char buf[BUFSIZ+1];
  31. struct sockaddr_in sa;
  32. struct hostent *hp;
  33. struct servent *sp;
  34.  
  35. /*
  36. -----------------------------------------------------------------------------
  37. Function name: tcp_connect()
  38. -----------------------------------------------------------------------------
  39. Parameters:    char *host        Name of the host to connect.
  40.         char *prot        The protocol to use.
  41. Return value:    returns a socket.
  42. Called by:    main() (agentc)
  43. Calls:        none
  44. Description:    Sets up a connection to the host using the protocol
  45.         specified by prot.
  46. -----------------------------------------------------------------------------
  47. */
  48.  
  49. int tcp_connect(host, prot)
  50. char *host;
  51. char *prot;
  52. {
  53.     int s;
  54.         int len;
  55.    
  56.         if((hp = gethostbyname(host)) == NULL) {
  57.                 fprintf(stderr, "%s: %s: no such host?\n", myname, host);
  58.                 exit(1);
  59.         }
  60.  
  61.         bcopy((char*)hp->h_addr, (char*)&sa.sin_addr, hp->h_length);
  62.         sa.sin_family = hp->h_addrtype;
  63.  
  64.         if((sp = getservbyname(prot, "tcp")) == NULL) {
  65.                 fprintf(stderr, "%s: No %s service on %s\n", myname, prot, host);
  66.                 exit(1);
  67.         }
  68.  
  69.         sa.sin_port = sp->s_port;
  70.  
  71.         if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
  72.                 perror("socket");
  73.                 exit(1);
  74.         }
  75.  
  76.         if(connect(s, &sa, sizeof(sa)) < 0 ) {
  77.                 perror("connect");
  78.                 exit(1);
  79.         }
  80.  
  81.     return(s);
  82. }
  83.  
  84. /*
  85. -----------------------------------------------------------------------------
  86. Function name: tcp_connect_listen()
  87. -----------------------------------------------------------------------------
  88. Parameters:    int port        The port on which to listen.
  89. Return value:    Returns a socket.
  90. Called by:    main() (agentd)
  91. Calls:        none
  92. Description:    Reserves a port on wich to listen on.
  93. -----------------------------------------------------------------------------
  94. */
  95.  
  96. int tcp_connect_listen(port)
  97. int port;
  98. {
  99.         int s;
  100.         int len;
  101.     char localhost[MAXHOSTNAME+1];
  102.  
  103.     gethostname(localhost, MAXHOSTNAME);
  104.     if((hp = gethostbyname(localhost)) == NULL) {
  105.                 fprintf(stderr, "%s: %s: no such host?\n", myname);
  106.                 exit(1);
  107.         }
  108.  
  109.         sa.sin_port = port;
  110.         bcopy((char*)hp->h_addr, (char*)&sa.sin_addr, hp->h_length);
  111.         sa.sin_family = hp->h_addrtype;
  112.  
  113.  
  114.         if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
  115.                 perror("socket");
  116.                 exit(1);
  117.         }
  118.  
  119.         if(bind(s, &sa, sizeof(sa)) < 0 ) {
  120.                 perror("bind");
  121.                 exit(1);
  122.         }
  123.  
  124.     listen(s, BACKLOG);
  125.  
  126.         return(s);
  127. }
  128.  
  129. /*
  130. -----------------------------------------------------------------------------
  131. Function name: tcp_send()
  132. -----------------------------------------------------------------------------
  133. Parameters:    int s        The socket on which the data is send.
  134.         char *data    Pointer to a buffer which contains the data
  135.                 to be send.
  136. Return value:    none
  137. Called by:    do_server(), help(), reg_user(), send_user_error(),
  138.         nytt(), nytt_ord(), new_words(), new_news(), 
  139.         hent_nye_innlegg(), get_list(), do_innlegg()
  140. Calls:        none
  141. Description:    Sends data to the given socket.
  142. -----------------------------------------------------------------------------
  143. */
  144.  
  145. void tcp_send(s, data)
  146. int s;
  147. char *data;
  148. {
  149.     if(write(s,data , strlen(data)) != strlen(data)) {
  150.                 fprintf(stderr, "%s: write error\n", myname);
  151.                 exit(1);
  152.         }
  153. }
  154.  
  155. /*
  156. -----------------------------------------------------------------------------
  157. Function name: tcp_answer()
  158. -----------------------------------------------------------------------------
  159. Parameters:    int s        The socket on wich to recieve data.
  160.         int f        File descriptor on which to write the data
  161.                 recieved.
  162. Return value:    none
  163. Called by:    none
  164. Calls:        none
  165. Description:    Reads data from a socket and writes them to a file.
  166. -----------------------------------------------------------------------------
  167. */
  168.  
  169. void tcp_answer(s, f)
  170. int s;
  171. int f;
  172. {
  173.     int len;
  174.     int more;
  175.     int width;
  176.     int read_ready;
  177.     fd_set read_socket;
  178.     struct timeval timeout;
  179.  
  180.     timeout.tv_sec = 4;
  181.     timeout.tv_usec = 5;
  182.  
  183.     width = (int) ulimit(4, 0);
  184.  
  185.     FD_ZERO(&read_socket);
  186.     FD_SET(s, &read_socket);
  187.  
  188.     while((read_ready = select(width, &read_socket, NULL, NULL, &timeout)) > 0) {
  189.         len = read(s, buf, BUFSIZ);
  190.         if(len <= 0) return;
  191.                 write(f, buf, len);
  192.         }
  193.     if(read_ready < 0) {
  194.         perror("select");
  195.         exit(1);
  196.     }
  197. }
  198.  
  199. /*
  200. -----------------------------------------------------------------------------
  201. Function name: get_msg()
  202. -----------------------------------------------------------------------------
  203. Parameters:    int s        Socket on which to recive data.
  204.         char okchar    A character indicating if everything went
  205.                 ok. This is matched against the first
  206.                 character recieved.
  207.         char uptochar    A character indicating when to stop reading
  208.                 from s.
  209.         char *buffer    The buffer to put the characters read.
  210.         int timeout    The time in seconds after a timeout will
  211.                 occur if no data is recieved at s.
  212. Return value:    -1 timeout occured
  213.          0 the okchar didn't match the first character read.
  214.          1 success
  215. Called by:    main() (agentc), do_innlegg()
  216. Calls:        none
  217. Description:    Recives data on s until uptochar is read.
  218. -----------------------------------------------------------------------------
  219. */
  220.  
  221. int get_msg( s, okchar, uptochar, buffer, time_out)
  222. int  s;
  223. char okchar;
  224. char uptochar;
  225. char *buffer;
  226. int  time_out;
  227. {
  228.     int len;
  229.         int width;
  230.         int read_ready;
  231.         fd_set read_socket;
  232.         struct timeval timeout;
  233.     char ch_read[3];
  234.     int teller = 0;
  235.  
  236.         timeout.tv_sec = time_out;
  237.         timeout.tv_usec = 0;
  238.  
  239.         width = (int) ulimit(4, 0);
  240.  
  241.         FD_ZERO(&read_socket);
  242.         FD_SET(s, &read_socket);
  243.  
  244.         while((read_ready = select(width, &read_socket, NULL, NULL, &timeout)) >
  245.  0) {
  246.                 len = read(s, ch_read, 1);
  247.         ch_read[1] = '\0';
  248.                 if(len <= 0)
  249.              return(-2);
  250.                 if(ch_read[0] == uptochar) {
  251.             buffer[teller] = '\0';
  252.             if(buffer[0] == okchar)
  253.                 return(1);
  254.             else return(0);
  255.         }
  256.         buffer[teller++] = ch_read[0];
  257.         }
  258.         if(read_ready < 0) {
  259.                 perror("select");
  260.                 exit(1);
  261.         }
  262.         else if(read_ready == 0 ) 
  263.                 return(-1);    
  264.  
  265. }
  266.  
  267. /*
  268. -----------------------------------------------------------------------------
  269. Function name: recv_upto()
  270. -----------------------------------------------------------------------------
  271. Parameters:    int s        Socket on wich to recieve data.
  272.         char uptochar    The stop character. This function reads data
  273.                 until this character is read.
  274.         char *buffer    The buffer in wich to put the data read.
  275.         int timeout    The time to wait for response on the socket.
  276. Return value:    -2 on error
  277.         -1 on timeout
  278.          1 on success
  279. Called by:    do_server(), get_list()
  280. Calls:        none
  281. Description:    This function reads data from the socket s until it reads
  282.         uptochar. The characters read is put into buffer.
  283. -----------------------------------------------------------------------------
  284. */
  285.  
  286. int recv_upto( s, uptochar, buffer, time_out)
  287. int  s;
  288. char uptochar;
  289. char *buffer;
  290. int  time_out;
  291. {
  292.         int len;
  293.         int width;
  294.         int read_ready;
  295.         fd_set read_socket;
  296.         struct timeval timeout;
  297.         char ch_read[3];
  298.         int teller = 0;
  299.  
  300.         timeout.tv_sec = time_out;
  301.         timeout.tv_usec = 0;
  302.  
  303.         width = (int) ulimit(4, 0);
  304.  
  305.         FD_ZERO(&read_socket);
  306.         FD_SET(s, &read_socket);
  307.  
  308.         while((read_ready = select(width, &read_socket, NULL, NULL, &timeout)) >
  309.  0) {
  310.                 len = read(s, ch_read, 1);
  311.                 ch_read[1] = '\0';
  312.                 if(len <= 0)
  313.                          return(-2);
  314.                 if(ch_read[0] == uptochar) {
  315.                         buffer[teller] = '\0';
  316.                         return(1);
  317.                 }
  318.                 buffer[teller++] = ch_read[0];
  319.         }
  320.         if(read_ready < 0) {
  321.                 perror("select");
  322.                 exit(1);
  323.         }
  324.         else if(read_ready == 0 )
  325.                 return(-1);
  326.  
  327. }
  328.  
  329. /*
  330. -----------------------------------------------------------------------------
  331. Function name: get_list()
  332. -----------------------------------------------------------------------------
  333. Parameters:    int s        The socket on which to recive.
  334.         int fp        The file on which to write the retrived data.
  335.         int timeout    How long, in seconds, the function should
  336.                 wait if it doesn't recieve any data.
  337. Return value:    1 on success    
  338. Called by:    hent_nye_innlegg(), new_words()
  339. Calls:        recv_upto(), tcp_send()
  340. Description:    The function recives data until it reads a '.' character.
  341.         The data is written to a file.
  342. -----------------------------------------------------------------------------
  343. */
  344.  
  345. int get_list(s, fp, time_out)
  346. int s;
  347. int fp;
  348. int time_out;
  349. {
  350.     char linje[BUFSIZ+1];
  351.     char skriv_ut[BUFSIZ+1];
  352.     char *buf;
  353.     int ferdig = 0;
  354.  
  355.     linje[0] = '\0';
  356.  
  357.     while(!ferdig) {
  358.         if(recv_upto(s,RETURN, linje, time_out) <= 0) {
  359.             tcp_send(s, "505 error or timeout - closing\n");
  360.             close(s);
  361.             exit(1);
  362.         }
  363.         buf = linje;
  364.         if(*buf == LINEFEED)
  365.             buf++;
  366.  
  367.         if((strlen(linje)==2) && (linje[1] == '.'))
  368.             ferdig = 1;
  369.         else {
  370.             sprintf(skriv_ut, "%s\n", buf);
  371.             write(fp, skriv_ut, strlen(skriv_ut));
  372.         }
  373.     }
  374.     return(1);
  375. }
  376.  
  377.